package conn

import (
	"log"
	"time"
)

var (
	packageStart = []byte{0x88, 0x88}
	packageEnd   = []byte{0x89, 0x89}
)

const (
	DefaultTimeout     = time.Second * 0 //默认超时时间(0表示不过期)
	DefaultTimeoutRead = time.Second * 0 //默认抄读时间,一般不设置,设置后会源源不断的空数据,并被过滤,当部分协议只有起始帧时,需要配置读取数据超时配合使用,确定结束位置
	DefaultTimeoutSend = time.Second * 0 //默认发送数据时间,0不做超时
	DefaultPing        = "ping"
	DefaultPong        = "pong"
)

// DefaultCloseFunc 默认关闭链接事件
func DefaultCloseFunc(msg *Msg) {
	log.Printf("[关闭][%s] %s\n", msg.Key(), msg.String())
}

// DefaultReadFunc 默认读取方法
// 读取只有起始帧的数据包时,需要和超时配合使用
func DefaultReadFunc(c *Conn) (bytes []byte, e error) {
	defer func() {
		switch string(bytes) {
		case string(append(append(packageStart, []byte(DefaultPing)...), packageEnd...)):
			e = c.Send(DefaultPong)
		}
	}()
	return defaultReadFunc(c, packageStart, packageEnd)
}

// ReadWithStartEnd 新建读取函数
func ReadWithStartEnd(packageStart, packageEnd []byte) func(*Conn) ([]byte, error) {
	return func(c *Conn) ([]byte, error) {
		return defaultReadFunc(c, packageStart, packageEnd)
	}
}

// ReadWithLine
// 读取数据,一行一行读取
// 注意非英文容易出现问题,有可能被切割 结尾
//func ReadWithLine(c *Conn) ([]byte, error) {
//	line, _, err := c.Reader.ReadLine()
//	return line, err
//}

// DefaultPrintFunc 默认打印读取数据,打印hex和ascii
func DefaultPrintFunc(tag string, msg *Msg) {
	log.Printf("[%s][%s] 长度:%d HEX:%s 内容:%s\n", tag, msg.Key(), msg.Len(), msg.HEX(), msg.String())
}

// PrintWithHEX 打印读取数据,打印hex
func PrintWithHEX(tag string, msg *Msg) {
	log.Printf("[%s][%s] 长度:%d HEX:%s\n", tag, msg.Key(), msg.Len(), msg.HEX())
}

// PrintWithASCII 打印读取数据,打印ascii
func PrintWithASCII(tag string, msg *Msg) {
	log.Printf("[%s][%s] %s\n", tag, msg.Key(), msg.String())
}

// DefaultSendFunc 默认发送数据处理函数
func DefaultSendFunc(bytes []byte) []byte {
	result := append(packageStart, bytes...)
	result = append(result, packageEnd...)
	return result
}

/*












 */

//默认读取方法
func defaultReadFunc(c *Conn, start, end []byte) (bytes []byte, e error) {
	for {
		b, err := c.ReadOne()
		if err != nil {
			return bytes, err
		}
		if len(start) > 0 && b == start[0] {
			bs := []byte{b}
			isStart := true
			for _, v := range start[1:] {
				b2, err := c.ReadOne()
				if err != nil {
					return bytes, err
				}
				bs = append(bs, b2)
				if b2 != v {
					isStart = false
					break
				}
			}
			if isStart && len(end) > 0 && len(bytes) == 0 {
				if true {
					bytes = bs
				} else {
					bytes = []byte{}
				}
			} else {
				bytes = append(bytes, bs...)
			}
		} else if len(end) > 0 && b == end[0] {
			bs := []byte{b}
			isEnd := true
			for _, v := range end[1:] {
				b2, err := c.ReadOne()
				if err != nil {
					return nil, err
				}
				bs = append(bs, b2)
				if b2 != v {
					isEnd = false
					break
				}
			}
			bytes = append(bytes, bs...)
			if isEnd {
				break
			}
		} else {
			bytes = append(bytes, b)
		}
	}
	return bytes, nil
}
